import time
from functools import wraps
from typing import Callable, Any, Optional
import logging

from config.settings import DATA_CONFIG

logger = logging.getLogger(__name__)

def retry_on_exception(
    retries: int = DATA_CONFIG['retry_count'],
    delay: int = DATA_CONFIG['retry_delay'],
    exceptions: tuple = (Exception,),
    on_retry: Optional[Callable] = None
) -> Callable:
    """
    装饰器：在发生异常时重试函数
    
    Args:
        retries: 最大重试次数
        delay: 重试延迟(秒)
        exceptions: 需要重试的异常类型
        on_retry: 重试时的回调函数
        
    Returns:
        装饰器函数
    """
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            last_exception = None
            
            for attempt in range(retries + 1):
                try:
                    return func(*args, **kwargs)
                except exceptions as e:
                    last_exception = e
                    
                    if attempt == retries:
                        logger.error(
                            f"函数 {func.__name__} 在 {retries} 次重试后仍然失败: {str(e)}"
                        )
                        raise
                    
                    logger.warning(
                        f"函数 {func.__name__} 执行失败 (尝试 {attempt + 1}/{retries}): {str(e)}"
                    )
                    
                    if on_retry:
                        on_retry(attempt, last_exception, *args, **kwargs)
                    
                    if delay > 0:
                        time.sleep(delay)
            
            return None
        
        return wrapper
    
    return decorator
